package datamining.algorithms.prefixspan;

import datamining.miner.chain.Extension;
import datamining.miner.chain.SearchLatticeNode;
import datamining.miner.general.Fragment;
import datamining.miner.general.Frequency;
import datamining.miner.general.SequenceFragment;
import datamining.sequence.IndexedItem;
import de.parsemis.algorithms.gSpan.GThreadEnvironment;

/**
 * <p>
 * 创建于 2012-12-11 下午8:37:03
 * 
 * @author xujinghu (jinghuxu@nudt.edu.cn) <br>
 *         Copyright 2012 xujinghu <br>
 *         Lisence: Apache
 */
public class PrefixSpanExtension<ItemType> implements Extension<ItemType> {

	protected IndexedItem<ItemType> subExtendItem;// 子序列扩展项
	protected SequenceFragment<ItemType> frag;// 扩展后的fragment，多个Extension共享

	/** used for the pool */
	transient PrefixSpanExtension<ItemType> next;

	private transient/* final */PThreadEnvironment<ItemType> tenv;

	/**
	 * 
	 * @author xujinghu
	 * @date 2012-12-19上午11:31:21
	 * @param code
	 */
	/**
	 * 对code进行扩展并保存fragment
	 * 
	 * @author xujinghu
	 * @date 2012-12-19上午11:34:45
	 * @param code
	 * @return 扩展后的标准编码
	 */
	public PrefixCode<ItemType> applyTo(PrefixCode<ItemType> code) {

		// TODO需完善
		PrefixCode<ItemType> newCode = tenv.getCode(getFragment(),
				getFragment().toSequence());// 采用简略方法，因为在序列挖掘中扩展序列的顺序是唯一的
		frag = newCode.toFragment();//存储结果
		
		return newCode;
	}

	public PrefixSpanExtension(IndexedItem<ItemType> subExtendItem,
			SequenceFragment<ItemType> frag, PThreadEnvironment<ItemType> tenv) {
		this.subExtendItem = subExtendItem;
		this.frag = frag;
		this.tenv = tenv;
	}

	@Override
	public int compareTo(Extension<ItemType> o) {
		return subExtendItem
				.compareTo(((PrefixSpanExtension<ItemType>) o).subExtendItem);
	}

	@Override
	public Frequency frequency() {
		return getFragment().frequency();
	}

	@Override
	public SequenceFragment<ItemType> getFragment() {
		return frag;
	}

	public IndexedItem<ItemType> getExtendItem() {
		return subExtendItem;
	}

	public String toString() {
		return subExtendItem.toString() + ": "
				+ frag.toString();
	}

	public void release(final PThreadEnvironment<ItemType> target) {
		if (target == tenv) {
			target.push(this);
		}
	}
}
